
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;

using System.Text.RegularExpressions;

using Swaf.BizObj;

namespace Swaf.Resource
{
	/// <summary>
	/// Main interface getting text processing done including powerful regular expression match and
	/// replace.
	/// </summary>
	public interface IResourceManager
	{
		IBizObj CurrentCulture { get;set;}
		IBizObj BuiltInCulture { get;}
		bool UsingBuiltInCulture { get;}

		/// <summary>
		/// Given a string of html with embeded SWAF macros, resolve all macros and
		/// return an HTLM string ready to be displayed in a browser.  
		/// </summary>
		/// <remarks>
		/// Simple macros such as $P1$ or $Home$ are replaced with the values directly associated
		/// with the given macro name.  Macro functions such as $Locate(namespaceName, resourceName)$
		/// are resolved by calculating a value and then replacing the macro function in the source
		/// string with the results of the function calculation.
		/// </remarks>
		/// <param name="str">The string with embed macros and macro functions to be parsed.</param>
		/// <returns>The source string with embed macros and macro functions replaced with the runtime values.</returns>
		string resolve(string str);
		string resolve(string str, IDictionary localMacros);

		/// <summary>
		/// Will do resolve on str using known macros, but limits the macros being replaced to either
		/// those names listed in <c>macroExceptions</c> or those names not listed in it depending on
		/// the <c>onlyExceptions</c> parameter.
		/// </summary>
		/// <param name="str"></param>
		/// <param name="macroExceptions"></param>
		/// <param name="onlyExceptions"></param>
		/// <returns></returns>
		string resolve(string str, IDictionary macroExceptions, bool onlyExceptions);

		/// <summary>
		/// Given the namespaceName, will attempt to locate the file with fileName by search the namespace
		/// locations defined in the application configuration.
		/// </summary>
		/// <param name="namespaceName">A defined namespace out of the application configuration</param>
		/// <param name="fileName">The filename to try and locate in the namespace locations</param>
		/// <returns>On succesful location of the file, a fully qualified url to access the file.<br/>
		/// On failure to locate the file, null.</returns>
		string getResourceUrl(string namespaceName, string fileName);

		/// <summary>
		/// Retrieveds the value of a specific macro or macro function 
		/// </summary>
		/// <param name="name">a defined macro or macro function from the application configuration</param>
		/// <returns>If a valid name is provided, the value of the given macro.  Otherwise, null.</returns>
		string getMacro(string name);

		/// <summary>
		/// Given the namespaceName, will attempt to locate the file by searching the namespace file system
		/// locations only.
		/// </summary>
		/// <param name="name">A defined namespace out of the application configuration</param>
		/// <param name="fileName"></param>
		/// <returns></returns>
		string getFileResourceUrl(string name, string fileName);

		/// <summary>Formats and returns the indicated message.
		/// </summary>
		string getMessage(object messageId, string defVal, params object[] replacements);

		string format(DateTime source, DateTimeFormats format);
		string format(short source, NumericFormats format);
		string format(int source, NumericFormats format);
		string format(long source, NumericFormats format);
		string format(double source, NumericFormats format);
		string format(float source, NumericFormats format);
		string format(decimal source, NumericFormats format);
		string format(uint source, NumericFormats format);
		string format(ulong source, NumericFormats format);
		string format(ushort source, NumericFormats format);

		DateTime dateFromString(string source);
		object numberFromString(string source, NumberTypes type);
		
		string generateRawPatternXml();

		/// <summary>Returns the Regex object associated with the specified regular expression <code>pattern</code>,
		/// string, but if <code>pattern</code> has errors, it does <em>not</em> throw an exception.
		/// This is used only when the caller is <em>sure</em> that the <code>pattern</code> is valid,
		/// typically when the <code>pattern</code> is a string literal.
		/// If there is an error in <code>pattern</code>, it puts a message in the log file.
		/// </summary>
		Regex knownGoodPattern(string pattern);
		
		/// <summary>Returns a human-readable explanation of what's wrong with the pattern,
		/// or returns null if the pattern is a valid regular expression.
		/// </summary>
		string patternErrorMessage(string pattern);

		/// <summary>
		/// Tries to match the regular expression <code>pattern</code> against the entire String <code>target</code>.
		/// The match succeeds if and only if the entire string <code>target</code> matches the pattern.</summary>
		/// <remarks>
		/// See 'contains()' for an alternative that searches for a match within <code>target</code>.
		/// The returned MatchResult object can be used to get details about the match.
		/// If <code>pattern</code> does not match the entire string <code>target</code>, the function returns <code>null</code>.
		/// throws PatternRepository.BadPattern when <code>pattern</code> is not a valid regular expression pattern.
		/// The exception object's getMessage() method can be used to get a human-readable
		/// description of why <code>pattern</code> was invalid.
		/// </remarks>
		Match matches(string pattern, string target);
		
		/// <summary>Tries to match the regular expression <code>pattern</code> against the entire String <code>target</code>.
		/// The match succeeds if and only if the entire string <code>target</code> matches the pattern.
		/// See 'contains()' for an alternative that searches for a match within <code>target</code>.
		/// The returned MatchResult object can be used to get details about the match.
		/// If <code>pattern</code> does not match the entire string <code>target</code>, the function returns <code>null</code>.
		/// </summary>
		Match matches(Regex pattern, string target);
		
		/// <summary>Tries to find a match of the regular expression <code>pattern</code> anywhere within the String <code>target</code>.
		/// The match succeeds if and only if anything within <code>target</code> matches the <code>pattern</code>.
		/// See 'matches()' for an alternative that does not search for a match within <code>target</code>.
		/// The returned MatchResult object can be used to get details about the match.
		/// If <code>pattern</code> does not match anywhere within <code>target</code>, the function returns <code>null</code>.
		/// @throws PatternRepository.BadPattern when <code>pattern</code> is not a valid regular expression pattern.
		/// The exception object's getMessage() method can be used to get a human-readable
		/// description of why <code>pattern</code> was invalid.
		/// </summary>
		Match contains(string pattern, string target);
			
		/// <summary>Tries to match the regular expression <code>pattern</code> against the beginning of string <code>target</code>.
		/// The match succeeds if and only if the pattern matches at the beginning of string <code>target</code>.
		/// See 'matches()' for an alternative that matches the entire string <code>target</code>.
		/// The returned MatchResult object can be used to get details about the match.
		/// If <code>pattern</code> does not match at the beginning of string <code>target</code>, the function returns <code>null</code>.
		/// @throws PatternRepository.BadPattern when <code>pattern</code> is not a valid regular expression pattern.
		/// The exception object's getMessage() method can be used to get a human-readable
		/// description of why <code>pattern</code> was invalid.
		/// </summary>
		Match matchesPrefix(string pattern, string target);
				
		/// <summary>Tries to match the regular expression <code>pattern</code> against the beginning of string <code>target</code>.
		/// The match succeeds if and only if the pattern matches at the beginning of string <code>target</code>.
		/// See 'matches()' for an alternative that matches the entire string <code>target</code>.
		/// The returned MatchResult object can be used to get details about the match.
		/// If <code>pattern</code> does not match at the beginning of string <code>target</code>, the function returns <code>null</code>.
		/// </summary>
		Match matchesPrefix(Regex pattern, string target);		
		
		/// <summary>Searches the <code>target</code> string for the specified regular expression <code>pattern</code>,
		/// and replaces all occurrences of the pattern with the specified replacement
		/// string literal, <code>literal</code>.
		/// </summary>
		/// <param name="pattern">The regular expression pattern used to search within <code>target</code>.
		/// </param>
		/// <param name="target">The String on which to perform replacements.
		/// </param>
		/// <param name="literal"The string literal used to replace pattern occurences.
		/// </param>
		/// <returns>
		/// A String comprising the <code>target</code> string with the replacements,
		/// if any, made. If no replacements are made, the returned String
		/// is the original input String.
		/// @throws PatternRepository.BadPattern when <code>pattern</code> is not a valid regular expression pattern.
		/// The exception object's getMessage() method can be used to get a human-readable
		/// description of why <code>pattern</code> was invalid.
		/// 
		/// </returns>
		string replace(string pattern, string target, string literal);
		
		/// <summary>Searches the <code>target</code> string for the specified regular expression <code>pattern</code>,
		/// and replaces all occurrences of the pattern with the specified replacement
		/// string literal, <code>literal</code>.
		/// </summary>
		/// <param name="">
		/// pattern The regular expression pattern used to search within <code>target</code>.
		/// </param>
		/// <param name="">
		/// target The String on which to perform replacements.
		/// </param>
		/// <param name="">
		/// literal The string literal used to replace pattern occurences.
		/// </param>
		/// <returns>
		/// A String comprising the <code>target</code> string with the replacements,
		/// if any, made. If no replacements are made, the returned String
		/// is the original input String.
		/// 
		/// </returns>
		string replace(Regex pattern, string target, string literal);
								
		/// <summary>Splits up the <code>target</code> String into strings matched
		/// between the specified delimiter: <code>pattern</code>.  There
		/// is no limit on the number of delimiters will be found.
		/// <p>Note: Unlike Perl's split() function, this does not add
		/// extra list elements for each of the matching submatches
		/// in <code>pattern</code>.  E.g., if <code>pattern</code> was "([,-])" and <code>target</code>
		/// was "8-12,15,18", Perl's split() would produce {"8", "-",
		/// "12", ",", "15"} but this split() method will produce
		/// {"8", "12", "15", "18"}.
		/// </summary>
		/// <param name="">
		/// pattern - The regular expression pattern used as a delimiter.
		/// </param>
		/// <param name="">
		/// target - The String to be split.
		/// </param>
		/// <returns>
		/// A IList containing the substrings of the input that occur
		/// between the regular expression delimiter occurences.
		/// @throws PatternRepository.BadPattern when <code>pattern</code> is not a valid regular expression pattern.
		/// The exception object's getMessage() method can be used to get a human-readable
		/// description of why <code>pattern</code> was invalid.
		/// 
		/// </returns>
		IList split(string pattern, string target);
				
		/// <summary>Splits up the <code>target</code> String into strings matched
		/// between the specified delimiter: <code>pattern</code>.</summary>
		/// <remarks>
		/// There is no limit on the number of delimiters will be found.
		/// <p>Note: Unlike Perl's split() function, this does not add
		/// extra list elements for each of the matching submatches
		/// in <code>pattern</code>.  E.g., if <code>pattern</code> was compiled from "([,-])" and <code>target</code>
		/// was "8-12,15,18", Perl's split() would produce {"8", "-",
		/// "12", ",", "15"} but this split() method will produce
		/// {"8", "12", "15", "18"}.</p></remarks>
		/// <param name="pattern">The regular expression pattern used as a delimiter.</param>
		/// <param name="target">The String to be split.</param>
		/// <returns>A IList containing the substrings of the input that occur
		/// between the regular expression delimiter occurences.</returns>
		IList split(Regex pattern, string target);

		string fixupForHttp(string txt);
		string fixupForXml(string txt);
		string fixupFromXml(string txt);
	}
}

